package cn.demoncat.util.mybatis.base;

import cn.demoncat.util.exception.BizRuntimeException;
import cn.demoncat.util.exception.ParamRuntimeException;
import cn.demoncat.util.lang.MapUtil;
import cn.demoncat.util.lang.ParamEmptyUtil;
import cn.demoncat.util.lang.ThreadUtil;
import cn.demoncat.util.lang.entity.MapSo;
import cn.demoncat.util.lang.entity.Result;
import cn.demoncat.util.mybatis.constant.MapperConstant;
import cn.demoncat.util.mybatis.constant.MapperConstant.FieldName;
import cn.demoncat.util.mybatis.entity.Pager;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * BaseServiceImpl
 *
 * 说明：
 * 1、只有在public方法中注解事务才能生效
 * 2、同一个类中，以最外层方法的事务为准。如果外层方法无事务，内层方法的事务不生效
 * 3、没有事务时，会发生脏读、不可重复读、幻读。注解@Transactional的隔离级别默认为可重复读
 * 4、单条sql不需要注解事务，因为失败时本身就未入库，所以不需要回滚
 * 5、多条sql必须要注解事务：@Transactional
 * 6、乐观锁更新需要注解为读已提交的事务：@Transactional(isolation = Isolation.READ_COMMITTED)
 * 7、只有在不同的service中才能开启独立的新事务：@Transactional(propagation=Propagation.REQUIRES_NEW)
 * 8、嵌套事务中（A调用B），如果B抛异常后A执行cache，将抛出UnexpectedRollbackException异常，这时必须B无事务或A也异常回滚
 *
 * 规范：
 * 1、为了不影响业务代码的事务管理，模板类中没有注解事务，调用者根据情况控制
 *
 * @author 延晓磊
 * 
 * @since 2016年3月16日
 */
public abstract class BaseServiceImpl<T extends BaseEntity<T, P>, P extends Serializable> implements BaseService<T, P> {

	/**
	 * 初始化DAO
	 */
	protected abstract BaseDao<T, P> getDao();

	/**
	 * 添加
	 * 
	 * 1、如果属性为null，将赋值字段为null或报错cannot be null，不会使用数据库默认值；建议在程序中赋默认值
	 * 2、如果赋值ID，使用自定义ID；如果ID为null，使用数据库自增
	 * 3、更新后可以通过o.getId()获取主键
	 * 4、如果使用INSERT INTO，插入失败时抛异常；如果使用INSERT IGNORE INTO，成功返回1，失败返回0
	 * 
	 * @param o
	 * @return 插入的记录数
	 */
	@Override
	public int save(T o) {
		if (o == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.getDao().save(o);
	}

	/**
	 * 批量添加
	 * 
	 * 1、如果属性为null，将赋值字段为null或报错cannot be null，不会使用数据库默认值；建议在程序中赋默认值
	 * 2、如果赋值ID，使用自定义ID；如果ID为null，使用数据库自增
	 * 3、更新后可以通过o.getId()获取主键
	 * 4、如果使用INSERT INTO，插入失败时抛异常；如果使用INSERT IGNORE INTO，成功返回1，失败返回0
	 * 
	 * @param os
	 * @return 插入的记录数
	 */
	@Override
	public int batchSave(List<T> os) {
		if (os == null || os.isEmpty()) {
			return 0;
		}
		return this.getDao().batchSave(os);
	}

	/**
	 * 根据ID删除
	 * 
	 * @param id
	 * @return 删除的记录数
	 */
	@Override
	public int delete(P id) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		Map<String, Object> condition = new HashMap<>(1);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().delete(condition);
	}

	/**
	 * 根据ID删除
	 *
	 * @param id
	 * @return 删除的数据，数据不存在/删除失败返回null
	 */
	@Override
	public T deleteAndGet(P id) {
		// 查询
		T o = this.getById(id);
		if (o != null) {
			// 删除
			Map<String, Object> condition = new HashMap<>(1);
			condition.put(MapperConstant.FieldName.ID, id);
			if (this.getDao().delete(condition) > 0) {
				return o;
			}
		}
		return null;
	}

	/**
	 * 
	 * 根据ID+条件删除
	 *
	 * @param id
	 * @param condition
	 * @return 删除的记录数
	 * 
	 * @author 延晓磊
	 */
	@Override
	public int delete(P id, Map<String, Object> condition) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().delete(condition);
	}

	/**
	 * 安全删除
	 * 
	 * @param id
	 * @param createUser
	 * @return 删除的记录数
	 */
	@Override
	public int delete(P id, Long createUser) {
		return this.delete(id, createUser, null);
	}

	/**
	 * 安全ID+条件删除
	 *
	 * @param id
	 * @param createUser
	 * @param condition
	 * 
	 * @return 删除的记录数
	 * 
	 * @author 延晓磊
	 */
	@Override
	public int delete(P id, Long createUser, Map<String, Object> condition) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.delete(id, condition);
	}

	/**
	 * 假删除(修改isDel字段)
	 * 
	 * @param id
	 * @return 删除的记录数
	 */
	@Override
	public int deleteFake(P id) {
		return this.deleteFake(id, null, null);
	}

	/**
	 * 
	 * ID+条件假删除
	 *
	 * @param id
	 * @param condition
	 * @return 删除的记录数
	 * 
	 * @author 延晓磊
	 */
	@Override
	public int deleteFake(P id, Map<String, Object> condition) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		condition.put(MapperConstant.FieldName.ID, id);
		Map<String, Object> fields = new HashMap<>(1);
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition, null);
	}

	/**
	 * 安全假删除(修改isDel字段)
	 * 
	 * @param id
	 * @param createUser
	 * @return 删除的记录数
	 */
	@Override
	public int deleteFake(P id, Long createUser) {
		return this.deleteFake(id, createUser, null);
	}

	/**
	 * 
	 * 安全ID+条件假删除
	 *
	 * @param id
	 * @param createUser
	 * @param condition
	 * @return 删除的记录数
	 * 
	 * @author 延晓磊
	 */
	@Override
	public int deleteFake(P id, Long createUser, Map<String, Object> condition) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		condition.put(MapperConstant.FieldName.ID, id);
		Map<String, Object> fields = new HashMap<>();
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition, null);
	}

	/**
	 * 批量条件删除
	 * 
	 * @param ids
	 * @return 删除的记录数
	 */
	@Override
	public int batchDelete(Collection<P> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return 0;
		}
		Map<String, Object> condition = new HashMap<>(1);
		condition.put(MapperConstant.ParamName.IDS, ids);
		return this.getDao().delete(condition);
	}

	/**
	 * 批量条件删除
	 * 
	 * @param condition
	 * @return 删除的记录数
	 */
	@Override
	public int batchDelete(Map<String, Object> condition) {
		return this.getDao().delete(condition);
	}
	
	/**
	 * 批量条件删除
	 * 
	 * @param ids
	 * @param condition
	 * @return 删除的记录数
	 */
	@Override
	public int batchDelete(Collection<P> ids, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return 0;
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		if (condition.isEmpty()) {
			return 0;
		}
		return this.getDao().delete(condition);
	}

	/**
	 * 安全批量条件删除
	 *
	 * @param createUser
	 * @param ids
	 *
	 * @return 删除的记录数
	 */
	@Override
	public int batchDelete(Long createUser, Collection<P> ids) {
		return this.batchDelete(createUser, ids, null);
	}

	/**
	 * 安全批量条件删除
	 * 
	 * @param createUser
	 * @param ids
	 * @param condition
	 * 
	 * @return 删除的记录数
	 */
	@Override
	public int batchDelete(Long createUser, Collection<P> ids, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.batchDelete(ids, condition);
	}

	/**
	 * 批量条件假删除
	 * 
	 * @param ids
	 * @param condition 
	 * @return 删除的记录数
	 */
	@Override
	public int batchDeleteFake(Collection<P> ids, Map<String, Object> condition) {
		Map<String, Object> fields = new HashMap<>();
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition, ids);
	}
	
	/**
	 * 批量条件假删除
	 * 
	 * @param condition 
	 * @return 删除的记录数
	 */
	@Override
	public int batchDeleteFake(Map<String, Object> condition) {
		Map<String, Object> fields = new HashMap<>();
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition);
	}

	/**
	 * 安全批量条件假删除
	 * 
	 * @param createUser
	 * @param ids
	 * @param condition 
	 * @return 删除的记录数
	 */
	@Override
	public int batchDeleteFake(Long createUser, Collection<P> ids, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return 0;
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		Map<String, Object> fields = new HashMap<>();
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition, ids);
	}

	/**
	 * 安全批量条件假删除
	 * 
	 * @param createUser
	 * @param condition 
	 * @return 删除的记录数
	 */
	@Override
	public int batchDeleteFake(Long createUser, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		Map<String, Object> fields = new HashMap<>();
		fields.put(MapperConstant.FieldName.IS_DEL, MapperConstant.FieldValue.ONE);
		return this.updateFields(fields, condition);
	}
	
	/**
	 * 更新
	 * 
	 * 1、排除null属性的字段
	 * 2、如果o或id为null，抛异常
	 * 
	 * @param o  
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o) {
		if (o == null || o.getId() == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.getDao().update(o);
	}

	/**
	 * 完整更新
	 * 
	 * 1、不排除null属性的字段
	 * 2、如果o或id为null，抛异常
	 * 
	 * @param o
	 * @return 更新的记录数
	 */
	@Override
	public int fullUpdate(T o) {
		if (o == null || o.getId() == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.getDao().fullUpdate(o);
	}

	/**
	 * 乐观锁更新(根据version字段进行CAS更新)
	 * 
	 * 1、设置事务为READ_COMMITTED，方便重试时可重复读取数据
	 * 2、调用本方法
	 * 3、循环无数次，查询数据、通过task修改数据、以version为条件更新
	 * 
	 * @param id	ID查询。未找到将抛异常
	 * @param task	对查询到的数据进行更新（修改对象的属性，变更引用无效）
	 * 
	 * @return 更新结果数据
	 */
	@Override
	public T update(P id, Consumer<T> task) {
		return update(id, task, Integer.MAX_VALUE);
	}

	/**
	 * 乐观锁更新(根据version字段进行CAS更新)
	 * 
	 * 1、设置事务为READ_COMMITTED，方便重试时可重复读取数据
	 * 2、调用本方法
	 * 3、循环times次，查询数据、通过task修改数据、以version为条件更新，超次数未更新成功时抛异常：BizRuntimeException.BUSY
	 * 
	 * @param id	ID查询。未找到将抛异常
	 * @param task	对查询到的数据进行更新（修改对象的属性，变更引用无效）
	 * @param times	重试次数（默认MapperConstant.REPEAT_LOCK次）
	 * 
	 * @return 更新结果数据
	 */
	@Override
	public T update(P id, Consumer<T> task, int times) {
		if (id == null || task == null) {
			throw ParamRuntimeException.NULL;
		}
		// 循环，每10次休眠100秒
		T o;
		int sleep = 0;
		for (int i = 0; i < times; i++) {
			// 查询数据（子类可以通过重写getById来实现不同的结果，如不存在时初始化）
			o = this.getById(id);
			if (o == null) {
				throw ParamRuntimeException.DATA_NULL;
			}
			// 修改数据
			task.accept(o);
			// 乐观锁更新（依赖代码生成器生成的Mapper中的version条件）
			if (this.getDao().update(o) > 0) {
				// 成功
				return o;
			}else{
				// 失败，重试
				if (sleep > 10) {
					// 休眠
					sleep = 0;
					ThreadUtil.sleepMillis(MapperConstant.REPEAT_SLEEP);
				}else{
					sleep ++;
				}
			}
		}
		// 繁忙
		throw BizRuntimeException.BUSY;
	}

	/**
	 * 条件更新
	 * 
	 * 1、排除null属性的字段
	 * 2、如果o为null，抛异常
	 * 3、如果o.id为null，将更新condition匹配的所有数据；如果o.id非null，将判断id对应的数据是否满足condition
	 * 
	 * @param o  
	 * @param condition
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o, Map<String, Object> condition) {
		if (o == null) {
			throw ParamRuntimeException.NULL;
		}
		Map<String, Object> params = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, o);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		return this.getDao().updateByCondition(params);
	}

	/**
	 * 完整条件更新
	 * 
	 * 1、不排除null属性的字段
	 * 2、如果o为null，抛异常
	 * 3、如果o.id为null，将更新condition匹配的所有数据；如果o.id非null，将判断id对应的数据是否满足condition
	 * 
	 * @param o  
	 * @param condition
	 * @return 更新的记录数
	 */
	@Override
	public int fullUpdate(T o, Map<String, Object> condition) {
		if (o == null) {
			throw ParamRuntimeException.NULL;
		}
		Map<String, Object> params = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, o);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		return this.getDao().fullUpdateByCondition(params);
	}

	/**
	 * 批量更新
	 * 
	 * 1、排除null属性的字段
	 * 2、如果o为null，抛异常
	 * 3、如果o.id为null，将更新ids数据
	 * 
	 * @param o  
	 * @param ids 要更新的数据集
	 * 
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o, Collection<P> ids) {
		return update(o, null, ids);
	}
	
	/**
	 * 批量条件更新
	 * 
	 * 1、排除null属性的字段
	 * 2、如果o为null，抛异常
	 * 3、如果o.id为null，将更新ids数据，并筛选condition条件
	 * 
	 * @param o  
	 * @param condition
	 * @param ids 要更新的数据集
	 * 
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o, Map<String, Object> condition, Collection<P> ids) {
		if (condition == null) {
			condition = new HashMap<>();
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return 0;
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		return update(o, condition);
	}
	
	/**
	 * 安全更新
	 * 
	 * @param o 
	 * @param createUser
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o, Long createUser) {
		return this.update(o, createUser, null);
	}

	/**
	 * 安全条件更新
	 * 
	 * @param o  
	 * @param createUser
	 * @param condition
	 * @return 更新的记录数
	 */
	@Override
	public int update(T o, Long createUser, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.update(o, condition);
	}

	/**
	 * 批量更新
	 * 
	 * 1、排除null属性的字段
	 * 2、如果os为null，抛异常
	 * 
	 * @param os  更新的对象集 
	 */
	@Override
	public void batchUpdate(List<T> os) {
		if (CollectionUtils.isNotEmpty(os)) {
			this.getDao().batchUpdate(os);
		}
	}

	/**
	 * 完整批量更新
	 * 
	 * 1、不排除null属性的字段
	 * 2、如果os为null，抛异常
	 * 
	 * @param os
	 */
	@Override
	public void batchFullUpdate(List<T> os) {
		if (CollectionUtils.isNotEmpty(os)) {
			this.getDao().batchFullUpdate(os);
		}
	}

	/**
	 * 批量条件更新
	 * 
	 * 1、排除null属性的字段
	 * 
	 * @param os  
	 * @param condition
	 */
	@Override
	public void batchUpdate(List<T> os, Map<String, Object> condition) {
		if (CollectionUtils.isNotEmpty(os)) {
			Map<String, Object> params = new HashMap<>(2);
			params.put(MapperConstant.ParamName.OBJS, os);
			params.put(MapperConstant.ParamName.CONDITION, condition);
			this.getDao().batchUpdateByCondition(params);
		}
	}

	/**
	 * 完整批量条件更新
	 * 
	 * 1、不排除null属性的字段
	 * 
	 * @param os
	 * @param condition
	 */
	@Override
	public void batchFullUpdate(List<T> os, Map<String, Object> condition) {
		if (CollectionUtils.isNotEmpty(os)) {
			Map<String, Object> params = new HashMap<>(2);
			params.put(MapperConstant.ParamName.OBJS, os);
			params.put(MapperConstant.ParamName.CONDITION, condition);
			this.getDao().batchFullUpdateByCondition(params);
		}

	}

	/**
	 * 安全批量更新
	 * 
	 * @param os  
	 * @param createUser
	 */
	@Override
	public void batchUpdate(List<T> os, Long createUser) {
		this.batchUpdate(os, createUser, null);
	}

	/**
	 * 
	 * 安全批量条件更新
	 * 
	 * @param os  
	 * @param condition
	 * @param createUser
	 */
	@Override
	public void batchUpdate(List<T> os, Long createUser, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		this.batchUpdate(os, condition);
	}

	/**
	 * 更新字段
	 * 
	 * @param id
	 * @param fields 字段Map
	 *            
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(P id, Map<String, Object> fields) {
		// 校验
		ParamEmptyUtil.checkEmpty(id,fields);
		// 更新
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> condition = new HashMap<>(1);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}
	
	/**
	 * 批量条件更新字段
	 * 
	 * @param fields  	字段Map 
	 * @param condition 修改条件
	 * @param ids 		修改的IDS
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Map<String, Object> condition, Collection<P> ids) {
		if (fields == null || fields.isEmpty()) {
			throw ParamRuntimeException.NULL;
		}
		if (condition == null) {
			condition = new HashMap<>(1);
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return 0;
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		Map<String, Object> params = new HashMap<>();
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		return this.getDao().updateFields(params);
	}

	/**
	 * 安全批量条件更新字段
	 *
	 * @param fields  	字段Map
	 * @param createUser
	 * @param ids 		修改的IDS
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Long createUser, Collection<P> ids) {
		return this.updateFields(fields, createUser, null, ids);
	}

	/**
	 * 安全批量条件更新字段
	 * 
	 * @param fields  	字段Map
	 * @param createUser
	 * @param condition 修改条件
	 * @param ids 		修改的IDS
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Long createUser, Map<String, Object> condition, Collection<P> ids) {
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.updateFields(fields, condition, ids);
	}

	/**
	 * 批量条件更新字段
	 * 
	 * @param fields  	字段Map 
	 * @param condition 修改条件
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Map<String, Object> condition) {
		return this.updateFields(fields, condition, null);
	}

	/**
	 * 安全批量条件更新字段
	 * 
	 * @param fields  	字段Map
	 * @param createUser
	 * @param condition 修改条件
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Long createUser, Map<String, Object> condition) {
		return this.updateFields(fields, createUser, condition, null);
	}
	
	/**
	 * 批量条件更新字段
	 * 
	 * @param fields  	字段Map 
	 * @param ids 		修改的IDS
	 * @return 更新的记录数
	 */
	@Override
	public int updateFields(Map<String, Object> fields, Collection<P> ids) {
		return this.updateFields(fields, null, null, ids);
	}

	/**
	 * 排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		Map<String, Object> condition = new HashMap<>(1);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 安全排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @param createUser
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort, Long createUser) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		Map<String, Object> condition = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.getDao().updateFields(params);
	}

	/**
	 * 条件排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @param condition
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort, Map<String, Object> condition) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		condition = condition == null ? new HashMap<>(1) : condition;
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort, Long updateUser, LocalDateTime updateTime) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		Map<String, Object> condition = new HashMap<>(1);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 安全排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @param createUser
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 *
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort, Long createUser, Long updateUser, LocalDateTime updateTime) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		Map<String, Object> condition = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.getDao().updateFields(params);
	}

	/**
	 * 条件排序
	 *
	 * @param id 数据的ID
	 * @param sort 数据的排序
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 * @param condition
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateSort(P id, Long sort, Long updateUser, LocalDateTime updateTime, Map<String, Object> condition) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkNull(sort);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		condition = condition == null ? new HashMap<>(1) : condition;
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新sort
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.SORT, sort);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 状态
	 * 
	 * @param id 数据的ID
	 * @param status 数据的状态
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		Map<String, Object> condition = new HashMap<>(1);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 安全状态
	 * 
	 * @param id  数据的ID
	 * @param status  数据的状态
	 * @param createUser
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status, Long createUser) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		Map<String, Object> condition = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.getDao().updateFields(params);
	}

	/**
	 * 条件状态
	 * 
	 * @param id 数据的ID
	 * @param status 数据的状态
	 * @param condition
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status, Map<String, Object> condition) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(1);
		condition = condition == null ? new HashMap<>(1) : condition;
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 状态
	 * 
	 * @param id 数据的ID
	 * @param status 数据的状态
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status, Long updateUser, LocalDateTime updateTime) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		Map<String, Object> condition = new HashMap<>(1);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 安全状态
	 * 
	 * @param id 数据的ID
	 * @param status 数据的状态
	 * @param createUser
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status, Long createUser, Long updateUser, LocalDateTime updateTime) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		Map<String, Object> condition = new HashMap<>(2);
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		if (createUser != null) {
			condition.put(MapperConstant.FieldName.CREATE_USER, createUser);
		}
		return this.getDao().updateFields(params);
	}

	/**
	 * 条件状态
	 * 
	 * @param id 数据的ID
	 * @param status 数据的状态
	 * @param updateUser 更新人
	 * @param updateTime 更新时间
	 * @param condition
	 * @return 更新的记录数(1表示正常)
	 */
	@Override
	public int updateStatus(P id, String status, Long updateUser, LocalDateTime updateTime, Map<String, Object> condition) {
		// 校验
		ParamEmptyUtil.checkEmpty(id);
		ParamEmptyUtil.checkBlank(status);
		// 条件
		Map<String, Object> params = new HashMap<>(2);
		Map<String, Object> fields = new HashMap<>(3);
		condition = condition == null ? new HashMap<>(1) : condition;
		params.put(MapperConstant.ParamName.OBJ, fields);
		params.put(MapperConstant.ParamName.CONDITION, condition);
		// 更新status
		fields.put(MapperConstant.FieldName.UPDATE_TIME, updateTime);
		fields.put(MapperConstant.FieldName.UPDATE_USER, updateUser);
		fields.put(MapperConstant.FieldName.STATUS, status);
		condition.put(MapperConstant.FieldName.ID, id);
		return this.getDao().updateFields(params);
	}

	/**
	 * 处理数据
	 * 
	 * @param id		ID
	 * @param handler	fn(原数据)
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月10日
	 */
	@Override
	public Result handler(P id, Function<T,Result> handler) {
		// 查询原数据
		T dbData = getById(id);
		if (dbData == null) {
			return Result.ERROR_DATA_NULL;
		}
		// 处理
		return handler.apply(dbData);
	}
	
	/**
	 * 通过ID查询对象
	 * 
	 * @param id
	 * @return 对象
	 */
	@Override
	public T getById(P id) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.getDao().getById(id);
	}

	/**
	 * 通过ID查询对象(悲观锁)
	 * 
	 * @param id
	 * @return 对象
	 */
	@Override
	public T getForUpdate(P id) {
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.getDao().getForUpdate(id);
	}

	/**
	 * 通过ID查询对象
	 * 
	 * @param id
	 * @param createUser
	 * @return 对象
	 */
	@Override
	public T getById(P id, Long createUser) {
		return getByCondition(MapSo.getInstance(MapperConstant.FieldName.ID, id, FieldName.CREATE_USER, createUser));
	}

	/**
	 * 通过ID查询对象
	 * 
	 * @param id
	 * @param createUser
	 * @param condition
	 * @return 对象
	 */
	@Override
	public T getById(P id, Long createUser, Map<String, Object> condition) {
		if (condition == null) {
			condition = new HashMap<>(2);
		}
		condition.put(FieldName.ID, id);
		if (createUser != null) {
			condition.put(FieldName.CREATE_USER, createUser);
		}
		return getByCondition(condition);
	}

	/**
	 * 通过ID查询对象
	 * 
	 * @param id
	 * @param condition
	 * @return 对象
	 */
	@Override
	public T getById(P id, Map<String, Object> condition) {
		if(MapUtil.isEmpty(condition)) {
			return getById(id);
		}else {
			condition.put(FieldName.ID, id);
			return getByCondition(condition);
		}
	}

	/**
	 * 根据条件查询，返回唯一对象 
	 * 
	 * @param  condition 	 
	 * @return null 或 对象（以 limit 1 查询列表，不负责校验是否有多个）
	 */
	@Override
	public T getByCondition(Map<String, Object> condition) {
		List<T> os = this.findAll(condition, 1);
		if (os == null || os.isEmpty()) {
			return null;
		} else {
			return os.get(0);
		}
	}

	/**
	 * 根据条件查询，返回唯一对象
	 * 
	 * @param condition
	 * @param sortColumns
	 * 
	 * @return 对象（以 limit 1 查询列表，不负责校验是否有多个）
	 */
	@Override
	public T getByCondition(Map<String, Object> condition, String sortColumns) {
		List<T> os = this.findAll(condition, 1, 1, sortColumns);
		if (os == null || os.isEmpty()) {
			return null;
		} else {
			return os.get(0);
		}
	}

	/**
	 * 根据查询条件和ids统计记录数
	 * 
	 * @param condition  
	 * @param ids  
	 * @return 记录数
	 */
	@Override
	public long countAll(Map<String, Object> condition, Collection<P> ids) {
		if (condition == null) {
			condition = new HashMap<>();
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return 0;
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		return this.getDao().countByCondition(condition);
	}

	/**
	 * 根据查询条件统计记录数
	 * 
	 * @param condition  
	 * @return 记录数
	 */
	@Override
	public long countAll(Map<String, Object> condition) {
		return this.countAll(condition, null);
	}

	/**
	 * 根据ids统计记录数
	 * 
	 * @param ids  
	 * @return 记录数
	 */
	@Override
	public long countAll(Collection<P> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return 0;
		}
		return this.countAll(null, ids);
	}

	/**
	 * 统计总记录数
	 * 
	 * @return 记录数
	 */
	@Override
	public long countAll() {
		return this.countAll(null, null);
	}

	/**
	 * 判断是否存在
	 *
	 * @param id
	 * @return
	 */
	@Override
	public boolean exists(P id){
		if (id == null) {
			throw ParamRuntimeException.NULL;
		}
		return this.exists(MapSo.getInstance("id",id));
	}

	/**
	 * 判断是否存在
	 *
	 * @param condition
	 * @return
	 */
	@Override
	public boolean exists(Map<String,Object> condition){
		if (condition == null) {
			condition = new HashMap<>(0);
		}
		return this.getDao().countByCondition(condition) > 0;
	}

	/**
	 * 全部查询 
	 * 
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll() {
		return this.findList(null, null, null);
	}

	/**
	 * 全部查询 
	 * 
	 * @param sortColumns  	排序方式 
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll(String sortColumns) {
		return this.findList(null, null, sortColumns);
	}

	/**
	 * 全部分页查询 
	 * 
	 * @param pageNum		页码：null/0/负数 == 首页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Integer pageNum, Integer pageSize) {
		return this.findAll(null, null, pageNum, pageSize, null);
	}

	/**
	 * 全部分页查询 
	 * 
	 * @param pageNum		页码：null/0/负数 == 首页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Integer pageNum, Integer pageSize, String sortColumns) {
		return this.findAll(null, null, pageNum, pageSize, sortColumns);
	}

	/**
	 * 根据ids查询 
	 * 
	 * @param ids			查询数据的id集
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll(Collection<P> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return new ArrayList<>();
		}
		return this.findList(null, ids, null);
	}

	/**
	 * 根据ids查询 
	 * 
	 * @param ids			查询数据的id集
	 * @param sortColumns  	排序方式 
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll(Collection<P> ids, String sortColumns) {
		if (CollectionUtils.isEmpty(ids)) {
			return new ArrayList<>();
		}
		return this.findList(null, ids, sortColumns);
	}

	/**
	 * 根据条件查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition) {
		return this.findList(condition, null, null);
	}

	/**
	 * 根据条件查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param sortColumns  	排序方式 
	 * @return 对象列表 
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition, String sortColumns) {
		return this.findList(condition, null, sortColumns);
	}

	/**
	 * 根据条件查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition, Integer pageSize) {
		return this.findAll(condition, null, null, pageSize, null);
	}

	/**
	 * 根据条件分页查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param pageNum		页码：null/0/负数 == 首页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition, Integer pageNum, Integer pageSize) {
		return this.findAll(condition, null, pageNum, pageSize, null);
	}

	/**
	 * 根据条件分页查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param pageNum		页码：null/0/负数 == 首页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition, Integer pageNum, Integer pageSize, String sortColumns) {
		return this.findAll(condition, null, pageNum, pageSize, sortColumns);
	}

	/**
	 * 根据条件和ids分页查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param ids			查询数据的id集
	 * @param pageNum		页码：null/0/负数 == 首页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 对象列表
	 */
	@Override
	public List<T> findAll(Map<String, Object> condition, Collection<P> ids, Integer pageNum, Integer pageSize,
			String sortColumns) {
		return this.findAll(condition, ids, pageNum, pageSize, sortColumns, false);
	}

	/**
	 * 全部分页查询，返回Pager
	 * 
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 分页对象
	 */
	@Override
	public Pager<T> findPage(Integer pageNum, Integer pageSize) {
		return this.findPage(null, pageNum, pageSize);
	}

	/**
	 * 根据条件分页查询，返回Pager
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 分页对象
	 */
	@Override
	public Pager<T> findPage(Map<String, Object> condition, Integer pageNum, Integer pageSize) {
		return this.findPage(condition, pageNum, pageSize, null);
	}

	/**
	 * 根据条件分页查询，返回Pager
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 分页对象
	 */
	@Override
	public Pager<T> findPage(Map<String, Object> condition, Integer pageNum, Integer pageSize, String sortColumns) {
		return this.findPage(condition, null, pageNum, pageSize, sortColumns);
	}

	/**
	 * 分页排序查询，返回Pager
	 * 
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 分页对象
	 */
	@Override
	public Pager<T> findPage(Integer pageNum, Integer pageSize, String sortColumns) {
		return this.findPage(null, null, pageNum, pageSize, sortColumns);
	}

	/**
	 * 根据条件和ids分页查询，返回Pager
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param ids			查询数据的id集
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式 
	 * @return 分页对象
	 */
	@Override
	public Pager<T> findPage(Map<String, Object> condition, Collection<P> ids, Integer pageNum, Integer pageSize,
			String sortColumns) {
		// 分页查询，结果转换为Pager
		return Pager.getPager(this.findAll(condition, ids, pageNum, pageSize, sortColumns, true));
	}

	/**
	 * 全部查询 
	 * 
	 * @return ID列表 
	 */
	@Override
	public List<P> findIds() {
		return findIds(null, null, null);
	}

	/**
	 * 全部查询 
	 * 
	 * @param sortColumns  	排序方式 
	 * @return ID列表 
	 */
	@Override
	public List<P> findIds(String sortColumns) {
		return findIds(null, null, sortColumns);
	}

	/**
	 * 根据ids查询 
	 * 
	 * @param ids			查询数据的id集
	 * @return ID列表 
	 */
	@Override
	public List<P> findIds(Collection<P> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return new ArrayList<>();
		}
		return findIds(null, ids, null);
	}

	/**
	 * 根据ids查询 
	 * 
	 * @param ids			查询数据的id集
	 * @param sortColumns  	排序方式 
	 * @return ID列表 
	 */
	@Override
	public List<P> findIds(Collection<P> ids, String sortColumns) {
		if (CollectionUtils.isEmpty(ids)) {
			return new ArrayList<>();
		}
		return findIds(null, ids, sortColumns);
	}

	/**
	 * 根据条件查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @return ID列表 
	 */
	@Override
	public List<P> findIds(Map<String, Object> condition) {
		return findIds(condition, null, null);
	}

	/**
	 * 根据条件查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param sortColumns  	排序方式 
	 * @return ID列表
	 */
	@Override
	public List<P> findIds(Map<String, Object> condition, String sortColumns) {
		return findIds(condition, null, sortColumns);
	}

	/**
	 * 根据条件和ids查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param ids			查询数据的id集
	 * @return ID列表
	 */
	@Override
	public List<P> findIds(Map<String, Object> condition, Collection<P> ids) {
		return findIds(condition, ids, null);
	}

	/**
	 * 根据条件和ids查询 
	 * 
	 * @param condition		查询条件 (null表示全部) 
	 * @param ids			查询数据的id集
	 * @param sortColumns  	排序方式 
	 * @return ID列表
	 */
	@Override
	public List<P> findIds(Map<String, Object> condition, Collection<P> ids, String sortColumns) {
		if (condition == null) {
			condition = new HashMap<>();
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return new ArrayList<>();
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		if (StringUtils.isNotBlank(sortColumns)) {
			condition.put(MapperConstant.ParamName.SORT_COLUMNS, sortColumns);
		}
		return this.getDao().findIds(condition);
	}

	/**
	 * 全部分页查询，返回Pager
	 *
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 分页对象
	 */
	@Override
	public Pager<P> findIdPage(Integer pageNum, Integer pageSize){
		return findIdPage(null, pageNum, pageSize, null);
	}

	/**
	 * 根据条件分页查询，返回Pager
	 *
	 * @param condition		查询条件 (null表示全部)
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @return 分页对象
	 */
	@Override
	public Pager<P> findIdPage(Map<String, Object> condition, Integer pageNum, Integer pageSize){
		return findIdPage(condition, pageNum, pageSize, null);
	}

	/**
	 * 分页排序查询，返回Pager
	 *
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式
	 * @return 分页对象
	 */
	@Override
	public Pager<P> findIdPage(Integer pageNum, Integer pageSize, String sortColumns){
		return findIdPage(null, pageNum, pageSize, sortColumns);
	}

	/**
	 * 根据条件和ids分页查询，返回Pager
	 *
	 * @param condition		查询条件 (null表示全部)
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns  	排序方式
	 * @return 分页对象
	 */
	@Override
	public Pager<P> findIdPage(Map<String, Object> condition, Integer pageNum, Integer pageSize, String sortColumns) {
		// 开始分页
		Pager.startPage(pageNum, pageSize);
		// 查询
		if (condition == null) {
			condition = new HashMap<>();
		}
		// 排序
		if (StringUtils.isNotBlank(sortColumns)) {
			condition.put(MapperConstant.ParamName.SORT_COLUMNS, sortColumns);
		}
		// 分页查询，结果转换为Pager
		return Pager.getPager(this.getDao().findIds(condition));
	}

	/**
	 * 根据条件和ids分页排序查询 
	 * 
	 * @param condition 	 
	 * @param ids			
	 * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
	 * @param pageSize  	页长：null/0/负数 == 10，最大10000
	 * @param sortColumns	排序方式 
	 * @param isPageQuery	是否分页查询（true表示findPage调用；false只分页查询列表，不返回分页数据）
	 * 
	 * @return 对象列表
	 */
	private List<T> findAll(Map<String, Object> condition, Collection<P> ids, Integer pageNum, Integer pageSize,
			String sortColumns, boolean isPageQuery) {
		// 开始分页
		if (isPageQuery) {
			Pager.startPage(pageNum, pageSize);
		} else {
			Pager.startList(pageNum, pageSize);
		}
		// 查询
		if (condition == null) {
			condition = new HashMap<>();
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return new ArrayList<>();
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		if (StringUtils.isNotBlank(sortColumns)) {
			condition.put(MapperConstant.ParamName.SORT_COLUMNS, sortColumns);
		}
		return this.getDao().findByCondition(condition);
	}

	/**
	 * 根据条件和ids排序查询，不带分页
	 * 
	 * @param condition 	 
	 * @param ids			
	 * @param sortColumns	排序方式 
	 * 
	 * @return 对象列表
	 */
	private List<T> findList(Map<String, Object> condition, Collection<P> ids, String sortColumns) {
		// 查询
		if (condition == null) {
			condition = new HashMap<>();
		}
		// IDS非null
		if(ids != null){
			if (ids.isEmpty()) {
				// IDS为空
				return new ArrayList<>();
			}else{
				// IDS非空
				condition.put(MapperConstant.ParamName.IDS, ids);
			}
		}
		if (StringUtils.isNotBlank(sortColumns)) {
			condition.put(MapperConstant.ParamName.SORT_COLUMNS, sortColumns);
		}
		return this.getDao().findByCondition(condition);
	}

	

	

}
